package com.example.teacherservice.service;

import com.example.teacherservice.dto.ClassInfo;
import com.example.teacherservice.dto.StudentWithClassesDTO;
import com.example.teacherservice.entity.Course;
import com.example.teacherservice.entity.StuClass;
import com.example.teacherservice.entity.StuCourse;
import com.example.teacherservice.entity.Student;
import com.example.teacherservice.exception.StudentNotFoundException;
import com.example.teacherservice.repository.CourseRepository;
import com.example.teacherservice.repository.StuClassRepository;
import com.example.teacherservice.repository.StuCourseRepository;
import com.example.teacherservice.repository.StudentRepository;
import jakarta.persistence.EntityNotFoundException;
import org.hibernate.Hibernate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class StudentService {

    @Autowired
    private StudentRepository studentRepository;

    @Autowired
    private StuClassRepository stuClassRepository;

    @Autowired
    private StuCourseRepository stuCourseRepository;

    public List<Student> searchStudents(String keyword) {
        return studentRepository.searchStudents(keyword);
    }

    @Transactional(readOnly = true)
    public List<Student> getAllStudents() {
        List<Student> students = studentRepository.findAll();

        // 预加载所有关联用户
        students.forEach(student -> {
            if (student.getUser() != null) {
                try {
                    Hibernate.initialize(student.getUser());
                } catch (EntityNotFoundException e) {
                    System.out.printf("无效用户关联: 学生ID={} 用户ID={}",
                            student.getId(), student.getUserId());
                    student.setUser(null);
                }
            }
        });

        return students;
    }

    @Transactional
    public int batchAddStudentsToClass(Long classId, List<Long> studentIds) {
        if (classId == null || studentIds == null || studentIds.isEmpty()) {
            throw new IllegalArgumentException("班级ID和学生ID列表不能为空");
        }

        // 获取已存在的关联
        List<StuClass> existing = stuClassRepository.findExistingByClassIdAndStudentIds(classId, studentIds);
        List<Long> existingStudentIds = existing.stream()
                .map(StuClass::getStuId)
                .collect(Collectors.toList());

        // 过滤掉已存在的学生
        List<Long> newStudentIds = studentIds.stream()
                .filter(id -> !existingStudentIds.contains(id))
                .collect(Collectors.toList());

        // 批量插入新关联
        LocalDateTime now = LocalDateTime.now();
        List<StuClass> newRelations = newStudentIds.stream()
                .map(studentId -> {
                    StuClass sc = new StuClass();
                    sc.setStuId(studentId);
                    sc.setClassId(classId);
                    sc.setCreateTime(now);
                    sc.setUpdateTime(now);
                    return sc;
                })
                .collect(Collectors.toList());

        stuClassRepository.saveAll(newRelations);

        return newStudentIds.size();
    }

    @Transactional
    public int removeStudentFromClass(Long classId, Long studentId) {
        return stuClassRepository.deleteByStuIdAndClassId(studentId, classId);
    }

    @Transactional
    public int batchRemoveStudentsFromClass(Long classId, List<Long> studentIds) {
        if (classId == null || studentIds == null || studentIds.isEmpty()) {
            throw new IllegalArgumentException("班级ID和学生ID列表不能为空");
        }
        return stuClassRepository.batchDeleteByClassIdAndStudentIds(classId, studentIds);
    }

    // 新增方法：根据userId获取学生信息
    public Student getStudentByUserId(Long userId) {
        return studentRepository.findByUserId(userId)
                .orElseThrow(() -> new StudentNotFoundException("未找到该用户对应的学生信息"));
    }

    // 新增方法：获取学生详细信息（包含用户信息）
    public Student getStudentDetailByUserId(Long userId) {
        return studentRepository.findWithUserByUserId(userId)
                .orElseThrow(() -> new StudentNotFoundException("未找到该用户对应的学生信息"));
    }

    public StudentWithClassesDTO getStudentWithClassesByUserId(Long userId) {
        Student student = studentRepository.findWithUserByUserId(userId)
                .orElseThrow(() -> new EntityNotFoundException("未找到该学生信息"));

        List<ClassInfo> classes = stuClassRepository.findClassesByStudentId(student.getId());

        return new StudentWithClassesDTO(student, classes);
    }

    // 在StudentService中添加
    public Long findStudentIdByUserId(Long userId) {
        return studentRepository.findByUserId(userId)
                .map(Student::getId)
                .orElse(null);
    }

    /**
     * 获取所有学生信息（不分页）
     * @return 所有学生列表
     */
    @Transactional(readOnly = true)
    public List<Student> getAllStudent() {
        return studentRepository.findAll(Sort.by("id").ascending());
    }

    /**
     * 根据ID获取学生详细信息（不加载用户信息）
     * @param studentId 学生ID
     * @return 学生实体
     */
    @Transactional(readOnly = true)
    public Student getStudentDetailById(Long studentId) {
        return studentRepository.findById(studentId)
                .orElseThrow(() -> new EntityNotFoundException("未找到ID为 " + studentId + " 的学生"));
    }

    @Autowired
    private CourseRepository courseRepository;

    public Map<Long, String> getCourseNamesByIds(List<Long> courseIds) {
        if (courseIds == null || courseIds.isEmpty()) {
            return Collections.emptyMap();
        }

        // 去重并过滤null值
        List<Long> distinctIds = courseIds.stream()
                .filter(Objects::nonNull)
                .distinct()
                .collect(Collectors.toList());

        // 查询课程信息
        List<Course> courses = courseRepository.findAllById(distinctIds);

        // 构建课程ID到名称的映射
        Map<Long, String> courseNameMap = new HashMap<>();
        for (Course course : courses) {
            if (course != null && course.getDeleted() == 0) { // 假设0表示未删除
                courseNameMap.put(course.getId(), course.getCourseName());
            }
        }

        return courseNameMap;
    }

    @Transactional
    public void addCourseToClassStudents(Long classId, Long courseId) {
        // 1. 获取班级所有学生ID
        List<Long> studentIds = stuClassRepository.findStudentIdsByClassId(classId);

        if (studentIds.isEmpty()) {
            return;
        }

        // 2. 检查哪些学生已经拥有该课程
        List<Long> existingStudentIds = stuCourseRepository.findStudentIdsByCourseIdAndStudentIds(courseId, studentIds);

        // 3. 过滤出需要添加课程的学生
        List<Long> newStudentIds = studentIds.stream()
                .filter(id -> !existingStudentIds.contains(id))
                .collect(Collectors.toList());

        // 4. 批量添加课程
        LocalDateTime now = LocalDateTime.now();
        List<StuCourse> newCourses = newStudentIds.stream()
                .map(studentId -> {
                    StuCourse sc = new StuCourse();
                    sc.setStuId(studentId);
                    sc.setCourseId(courseId);
                    sc.setCreateTime(now);
                    return sc;
                })
                .collect(Collectors.toList());

        stuCourseRepository.saveAll(newCourses);
    }

    /**
     * 获取班级所有学生ID
     * @param classId 班级ID
     * @return 学生ID列表
     */
    public List<Long> getStudentIdsByClassId(Long classId) {
        return stuClassRepository.findStudentIdsByClassId(classId);
    }
}